///////////////////////////////////////////////////////////////////////////////////////////////////
// Illusion Ray Development Kit (IDK)           Copyright (c) 2010 ( dimitriy.martynenko@gmail.com )
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2010-05-22
// Updated : ...
// Licence : NEW BSD
// Info	   : "SCL" Safe Code Lib (for C++ unmanaged)
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

namespace System
{
	namespace Module
	{
		class IModuleManager;

		namespace ModuleType
		{
			enum Enum
			{
				GameSystem		= 'A',
				CoreSystem		= 'B',
				RenderSystem	= 'C',
				SoundSystem		= 'D',
				DBSystem		= 'E',
				UISystem		= 'F',
				OtherSystem		= 'Z'
			};
		}

		class ModuleEventInitialize : public Event
		{
		protected:
			ModuleType::Enum mInitType;
		protected:
			explicit ModuleEventInitialize(ModuleType::Enum enm) : Event(EventCode::ModuleInit)
			{
				mInitType = enm;
			}
		public:
			ModuleType::Enum GetInitializeType(void) const
			{
				return mInitType;
			}
		};

		template<typename TCast>
		class ModuleEventInitializeType : public ModuleEventInitialize
		{
		protected:
			ref<TCast> mModule;
		public:
			ModuleEventInitializeType(ModuleType::Enum enm, ref<TCast> module) 
				: ModuleEventInitialize(enm), mModule(module)
			{}

			ref<TCast> GetModule(void) const
			{
				return mModule;
			}
		};


		class IModuleManager : virtual public IObject
		{
		public:
			virtual void SendEvent(const Event& evnt) = 0;
		};


		struct IModule : virtual public INameable
		{
			typedef IModule * (*PInitModuleCall) (IModuleManager& manager);
			virtual void AcceptEvent(const Event& evnt) = 0;
			virtual void OnInit(void) = 0;
			virtual void OnStart(void) = 0;
			virtual ModuleType::Enum GetInitializeType(void) = 0;
			virtual void OnUpdate(float dt) = 0;
			virtual void OnActive(bool active) = 0;
			virtual void OnFinish(void) = 0;
		};

		template<typename ThreadUsage = Platform::TThread<TObject> >
		class TModule : public ThreadUsage, virtual public IModule
		{
			IDKClass;
		private:
			IModuleManager& mManager;
		protected:
			IModuleManager& GetManager()
			{
				return mManager;
			}
		public:
			TModule(IModuleManager& manager) : mManager(manager) {}
		};
	}
}

using namespace System::Module;